package com.caochenlei.array;

public class VariableArray<T> {
    private T[] elements;                           //存储元素的数组
    private int size;                               //存储元素的个数

    public VariableArray(int capacity) {
        this.elements = (T[]) new Object[capacity]; //初始化数组
        this.size = 0;                              //初始化长度
    }

    //获取数组当前大小
    public int size() {
        return size;
    }

    //判断数组是否为空
    public boolean isEmpty() {
        return size == 0;
    }

    //检查下标是否合法
    public void checkIndex(int index) {
        if (index < 0 || (size - 1) < index) {
            throw new IndexOutOfBoundsException("数组下标越界异常，请检查数组的下标！");
        }
    }

    //获取指定位置元素
    public T get(int i) {
        //下标检查
        checkIndex(i);
        //返回元素
        return elements[i];
    }

    //向数组中添加元素
    public void add(T t) {
        //动态扩容
        if (size == elements.length) {
            resize(2 * elements.length);
        }
        //添加元素
        elements[size++] = t;
    }

    //指定位置添加元素
    public void add(int i, T t) {
        //下标检查
        checkIndex(i);
        //动态扩容
        if (size == elements.length) {
            resize(2 * elements.length);
        }
        //元素后移
        for (int index = size; index > i; index--) {
            elements[index] = elements[index - 1];
        }
        //添加元素
        elements[i] = t;
        //个数加一
        size++;
    }

    //删除指定位置元素
    public T remove(int i) {
        //下标检查
        checkIndex(i);
        //记录元素
        T current = elements[i];
        //元素前移
        for (int index = i; index < size - 1; index++) {
            elements[index] = elements[index + 1];
        }
        //个数减一
        size--;
        //动态缩容
        if (size < elements.length / 4) {
            resize(elements.length / 2);
        }
        //返回元素
        return current;
    }

    //正向查找t元素第一次出现的位置
    public int indexOf(T t) {
        for (int i = 0; i < size; i++) {
            if (elements[i].equals(t)) {
                return i;
            }
        }
        return -1;
    }

    //反向查找t元素第一次出现的位置
    public int lastIndexOf(T t) {
        for (int i = size - 1; i > -1; i--) {
            if (elements[i].equals(t)) {
                return size - 1 - i;
            }
        }
        return -1;
    }

    //扩容缩容核心代码
    public void resize(int newCapacity) {
        //定义一个临时数组，指向原来的数组
        T[] temp = elements;
        //创建一个新数组
        elements = (T[]) new Object[newCapacity];
        //把原来数组元素拷贝到新数组中即可
        for (int i = 0; i < size; i++) {
            elements[i] = temp[i];
        }
    }
}
